#ifndef _BRECTIFY_H_
#define _BRECTIFY_H_

#include <blackbox/bases/csyncbox.h>
#include <blackbox/cimageout.h>
#include <blackbox/cdatain.h>
#include <buola/cv/opencv.h>

//necessary guarantees:
//- OnInput is only called if all inputs contain valid data
//- no input can change while OnInput is being executed

namespace buola { namespace blackbox {

BB_DECLARE_BASIC_DATA_TYPE(cvi::CStereoParameters,"CStereoParameters");

template<typename tPixel>
class BRectify : public CSyncBox
{
public:
    BRectify()
        :	iStereoParameters(this,"stereo parameters")
        ,	iLeftImage(this,"left image in")
        ,	iRightImage(this,"right image in")
        ,	oLeftImage(this,"left image out")
        ,	oRightImage(this,"right image out")
    {}

protected:
    virtual void OnClock()
    {
        const CImage<tPixel> &lLeftIn=iLeftImage.Get();
        const CImage<tPixel> &lRightIn=iRightImage.Get();

//        bool lSizeChanged=false;

        if(iStereoParameters.Changed()) //will be true first time we get to OnInput
        {
            const cvi::CStereoParameters &lParams=iStereoParameters.Get();

            cvi::init_optimal_rectify_map(mRectifyMap,lParams);
        }

        CImage<tPixel> lLeftOut=oLeftImage.GetNewImage(CSize_i(mRectifyMap.Width(),mRectifyMap.Height()));
        CImage<tPixel> lRightOut=oRightImage.GetNewImage(CSize_i(mRectifyMap.Width(),mRectifyMap.Height()));

        cvi::rectify(lLeftIn.View(),lLeftOut.View(),
                        lRightIn.View(),lRightOut.View(),mRectifyMap);

        oLeftImage.PushImage(lLeftOut);
        oRightImage.PushImage(lRightOut);
    }

public:
    CDataIn<cvi::CStereoParameters> iStereoParameters;
    CDataIn<CImage<tPixel>> iLeftImage;
    CDataIn<CImage<tPixel>> iRightImage;

    CImageOut<tPixel> oLeftImage;
    CImageOut<tPixel> oRightImage;

private:
    cvi::CRectifyMap mRectifyMap;
};

/*namespace blackbox*/ } /*namespace buola*/ }

#endif
